#include "alchemy.h"

// The first 4 bytes of alchemy's memory are used for swap space.
#define VAL_ADDR 0

package { // the package is flash.utils .. but this is set in the makefile

  // These algorithms are from:
  // http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Approximations_that_depend_on_IEEE_representation
  // and are around 5 times faster than the equivalent Math.sqrt() calls
  public class FastMath {

    // Computes the 'fast inverse square root' of a Vector of Numbers
    // Each number is replaced with an approximation of 1 / sqrt(x)
    public static function invSqrt(vec:Vector.<Number>):void
    {
      var i:int = 0, s:int = vec.length, x:Number, x2:Number;
      while (i < s) {
        x = vec[i];
        storeFloat32(x, VAL_ADDR);
        x2 = x * 0.5;
        storeInt32(0x5f375a86 - (loadInt32(VAL_ADDR) >> 1), VAL_ADDR);
        x = loadFloat32(VAL_ADDR); 
        vec[i] = x * (1.5 - x2 * x * x);
        i = i + 1;
      }
    }

    // Each number in a Vector of Numbers is replaced with an
    // approximation of its square root.
    public static function sqrt(vec:Vector.<Number>):void
    {
      var i:int = 0, s:int = vec.length;
      while (i < s) {
        storeFloat32(vec[i], VAL_ADDR);
	// (1<<29) - (1<22) - 0x4c000 = 0x1fbb4000
        storeInt32((loadInt32(VAL_ADDR) >> 1) + 0x1fbb4000, VAL_ADDR);
        vec[i] = loadFloat32(VAL_ADDR);
        i = i + 1;
      }
    }
  }
}
